package com.hh.front.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.hh.common.constants.Constants;
import com.hh.common.dto.RegisterImAccountDTO;
import com.hh.common.exception.HhException;
import com.hh.common.model.user.User;
import com.hh.common.response.AuthLoginResponse;
import com.hh.common.response.CommonResult;
import com.hh.common.token.FrontTokenComponent;
import com.hh.common.utils.DateUtil;
import com.hh.common.utils.RandomCodeUtils;
import com.hh.common.vo.merchant.MerAppIdInfoVo;
import com.hh.common.vo.user.UserInvitationCodeInfoVo;
import com.hh.common.vo.wx.UserLoginGetOpenIdVo;
import com.hh.front.dto.WxMaJscodeResultErrorResult;
import com.hh.front.request.AuthLoginRequest;
import com.hh.front.service.WxUserInfoService;
import com.hh.front.service.WxUserMaService;
import com.hh.service.service.UserService;
import com.hh.service.service.im.ImUserService;
import com.hh.service.service.impl.message.producer.UserImProducerMessage;
import com.hh.service.service.merchant.MerchantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WxUserInfoServiceImpl implements WxUserInfoService {
    private static final String WX_SESSION_ID = "wx_session_id:";

    @Value("${wx.appid}")
    private String appId;

    @Value("${wx.secret}")
    private String secret;

    @Autowired
    private WxUserMaService wxUserMaService;

    @Autowired
    private FrontTokenComponent tokenComponent;

    @Autowired
    private UserService userService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private ImUserService imUserService;

    @Autowired
    private UserImProducerMessage userImProducerMessage;

    /**
     * 微信小程序授权登录
     * @param request
     * @return
     */
    @Override
    public CommonResult<AuthLoginResponse> authLogin(AuthLoginRequest request) {
        String jsCode = request.getJsCode();
        String phoneCode = request.getPhoneCode();
        if(StrUtil.isBlank(jsCode)){
            return CommonResult.failed("临时登录凭证code不能为空");
        }
        if(StrUtil.isBlank(phoneCode)){
            return CommonResult.failed("手机号获取凭证code不能为空");
        }

        String merId = tokenComponent.getMerId();
        if(!Constants.PLATFORM_MER_ID.equals(merId)){
            //获取商户的appId和secret
            MerAppIdInfoVo merAppIdInfoVo = merchantService.getMerAppIdById(merId);
            if(ObjectUtil.isNull(merAppIdInfoVo)){
                throw new HhException("商户信息异常");
            }
            this.appId = merAppIdInfoVo.getMerAppId();
            this.secret = merAppIdInfoVo.getMerAppSecret();
        }
        Map<String, String> params = new HashMap<>(4);
        params.put("appid", this.appId);
        params.put("secret", this.secret);
        params.put("js_code", jsCode);

        try {
            //获取用户openId
            WxMaJscodeResultErrorResult sessionInfo = wxUserMaService.getSessionInfo(params);
            String openId = sessionInfo.getOpenid();
            UserLoginGetOpenIdVo userLoginGetOpenIdVo = userService.getByOpenId(openId);

            User user = new User();
            Integer userId;
            String imUserId;
            //判断用户是否注册，没有注册直接注册，注册了刷新token
            if(ObjectUtil.isNull(userLoginGetOpenIdVo)){
                //获取用户手机号
                String userPhone = wxUserMaService.getNewPhoneNoInfo(phoneCode, appId, secret);

                user.setOpenId(openId);
                user.setImUid(RandomCodeUtils.generateShortUuid());
                user.setPhone(userPhone);
                user.setUserType(Constants.USER_LOGIN_TYPE_PROGRAM);
                Date nowDate = DateUtil.nowDateTime();
                user.setCreateTime(nowDate);
                user.setAvatar(Constants.USER_DEFAULT_AVATAR_CONFIG_KEY);
                user.setLastLoginTime(nowDate);
                user.setMerId(merId);
                String phoneLastFour = userPhone.substring(userPhone.length() - 4);
                user.setNickname("新兰" + phoneLastFour);

                user.setIntegral(0);
                user.setInvitationCode(RandomCodeUtils.generateShortUuid());

                if(StrUtil.isNotBlank(request.getInvitationCode())){
                    //有邀请码，需要绑定分销关系
                    //验证邀请码的合法性
                    UserInvitationCodeInfoVo userByInvitationCode = userService.getUserByInvitationCode(request.getInvitationCode());
                    if(ObjectUtil.isNotNull(userByInvitationCode)){
                        user.setSpreadUid(userByInvitationCode.getUid());
                    }
                }
                userService.save(user);
                userId = user.getUid();
                imUserId = user.getImUid();

                //注册账号并自动拉进群消息投递到mq
                RegisterImAccountDTO registerImAccountDTO = new RegisterImAccountDTO();
                registerImAccountDTO.setImUserId(imUserId);
                registerImAccountDTO.setAvatar(user.getAvatar());
                registerImAccountDTO.setNickname(user.getNickname());
                userImProducerMessage.registerImAccount(registerImAccountDTO);
            }else {
                userId = userLoginGetOpenIdVo.getUid();
                imUserId = userLoginGetOpenIdVo.getImUid();
            }
            String token = tokenComponent.createToken(userId);
            AuthLoginResponse authLoginResponse = new AuthLoginResponse();
            authLoginResponse.setToken(token);
            authLoginResponse.setImUserId(imUserId);

            return CommonResult.success(authLoginResponse,"获取令牌成功");
        }catch (Exception e){
            return CommonResult.failed(e.getMessage());
        }
    }
}
